package com.ht.oss.service;

import cn.hutool.core.io.IORuntimeException;
import cn.hutool.crypto.digest.DigestUtil;
import com.ht.oss.config.BucketsConfig;
import com.ht.oss.dao.OssDao;
import com.ht.oss.exceptions.BucketNotExistException;
import com.ht.oss.obj.Bucket;
import com.ht.oss.utils.GlobalThreadPool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.util.Map;

@Service
public class OssService {

    @Autowired
    BucketsConfig bucketsConfig;

    @Autowired
    OssDao ossDao;

    @Autowired
    GlobalThreadPool globalThreadPool;

    /**
     * 上传文件到 obj bucket 中，文件将没有类型
     * @param data 文件数据
     * @return 文件md5
     * @throws IOException 文件写入本地异常
     */
    public String upload(byte[] data) throws IOException {
        String md5 = DigestUtil.md5Hex(data);
        Bucket bucket = ossDao.getBucketByName(bucketsConfig.getObjBucket());
        if (bucket == null) {
            throw new BucketNotExistException();
        }
        // 文件已经存在
        if (bucket.getContent().containsKey(md5)) {
            return md5;
        }
        // 异步的方式可能产生并发问题
        // globalThreadPool.execute(() -> {
            try {
                ossDao.upload(data, bucket, md5);
            } catch (IOException e) {
                throw new IORuntimeException(e);
            }
        // });
        return md5;
    }

    /**
     * 上传文件
     * @param data 文件数据
     * @param bucketName 文件目标 bucket
     * @param type 文件类型
     * @return 文件 md5
     * @throws IOException 文件写入本地异常
     */
    public String upload(byte[] data, String bucketName, String type) throws IOException {
        String md5 = DigestUtil.md5Hex(data);
        Bucket bucket = ossDao.getBucketByName(bucketName);
        if (bucket == null) {
            throw new BucketNotExistException();
        }
        // 文件已经存在
        if (bucket.getContent().containsKey(md5)) {
            return md5;
        }
        // globalThreadPool.execute(() -> {
            try {
                ossDao.upload(data, bucket, md5, type);
            } catch (IOException e) {
                throw new IORuntimeException(e);
            }
        // });
        return md5;
    }

    /**
     * 下载文件
     * @param bucketName 文件名称
     * @param md5 文件 md5
     * @return 文件
     */
    public File download(String bucketName, String md5) {
        Bucket bucket = ossDao.getBucketByName(bucketName);
        if (bucket == null) {
            return null;
        }
        Map<String, File> content = bucket.getContent();
        File file = content.get(md5);
        if (file == null || !file.exists()) {
            return null;
        }
        return file;
    }

    /**
     * 删除文件
     * @param bucketName 文件 bucket
     * @param md5 文件 md5
     * @return 操作是否成功
     */
    public boolean deleteFile(String bucketName, String md5) {
        Bucket bucket = ossDao.getBucketByName(bucketName);
        File file = bucket.getContent().get(md5);
        if (file == null) {
            return true;
        }
        bucket.getContent().remove(md5);
        return file.delete();
    }
}
